package io.xxx.cyb.sync.impl

import com.alibaba.fastjson.JSONObject
import io.xxx.cyb.model.Document
import io.xxx.cyb.model.Store
import io.xxx.cyb.sync.Porter
import io.xxx.cyb.util.dateTimeFormatter
import io.xxx.cyb.util.toJSONString
import io.xxx.cyb.util.toLocalDateTime
import org.springframework.web.util.UriComponentsBuilder
import java.time.LocalDateTime

/**
 * 孩子王
 */
abstract class HzwPorter(sid: String) : Porter(sid) {

    private val httpUrl = "http://dapopen.haiziwang.com/pop/"

    protected abstract val path: String

    protected fun getResponse(
        store: Store,
        startTime: LocalDateTime,
        endTime: LocalDateTime,
        timeParamType: Int = 2,
        pageNo: Long = 1,
    ): JSONObject {
        val url = UriComponentsBuilder
            .fromHttpUrl(httpUrl)
            .path(path)
            .queryParam("appkey", store.appKey)
            .queryParam("loginName", store.accessToken)
            .queryParam("jsonStr", buildRequest(startTime, endTime, timeParamType, pageNo).toJSONString())
            .toUriString()
        val response = restTemplate.getForEntity(url, JSONObject::class.java).body!!
        if (response.getString("errorCode") != "0") {
            throwException(javaClass.simpleName, path, response.getString("errorCode"), response.getString("message"))
        }
        return response
    }

    private fun buildRequest(
        startTime: LocalDateTime,
        endTime: LocalDateTime,
        timeParamType: Int, // 1. 创建时间，2. 更新时间
        pageNo: Long = 1,
    ): Map<String, String> {
        return mapOf(
            "startTime" to startTime.format(dateTimeFormatter),
            "endTime" to endTime.format(dateTimeFormatter),
            "page" to pageNo.toString(),
            "pageSize" to pageSize.toString(),
            "timeParamType" to timeParamType.toString()
        )
    }
}

// 订单
open class HzwTradePorter(sid: String) : HzwPorter(sid) {

    override val path = "order.list"

    override fun getParameters(store: Store): Pair<List<Any>, Boolean> {
        return listOf(2) to false
    }

    override fun getCount(store: Store, startTime: LocalDateTime, endTime: LocalDateTime, parameter: Any?): Long? {
        val response = getResponse(store, startTime, endTime, parameter as Int)
        return response.getLong("totalNum")
    }

    override fun getData(
        store: Store,
        startTime: LocalDateTime,
        endTime: LocalDateTime,
        parameter: Any?,
        pageNo: Long,
    ): List<Document>? {
        val response = getResponse(store, startTime, endTime, parameter as Int)
        return response.getJSONArray("data").map {
            @Suppress("unchecked_cast")
            val value = JSONObject(it as Map<String, Any>)
            Document(
                value.getString("dealCode"),
                value,
                value.getLong("LastUpdateTime").toLocalDateTime()
            )
        }
    }
}

@Suppress("unused")
class HzwTradeProcurator(sid: String) : HzwTradePorter(sid) {

    override val cron = "0/10 * * * * ?"

    override fun getParameters(store: Store): Pair<List<Any>, Boolean> {
        return listOf(1) to false
    }
}

// 退单
open class HzwRefundPorter(sid: String) : HzwPorter(sid) {

    override val path = "refund.orderList"

    override fun getParameters(store: Store): Pair<List<Any>, Boolean> {
        return listOf(2) to false
    }

    override fun getCount(store: Store, startTime: LocalDateTime, endTime: LocalDateTime, parameter: Any?): Long? {
        val response = getResponse(store, startTime, endTime, parameter as Int)
        return response.getLong("totalNum")
    }

    override fun getData(
        store: Store,
        startTime: LocalDateTime,
        endTime: LocalDateTime,
        parameter: Any?,
        pageNo: Long,
    ): List<Document>? {
        val response = getResponse(store, startTime, endTime, parameter as Int)
        return response.getJSONArray("data").map {
            @Suppress("unchecked_cast")
            val value = JSONObject(it as Map<String, Any>)
            Document(
                value.getString("dealCode"),
                value.getString("dealCode"),
                value,
                value.getString("update_time").toLocalDateTime()
            )
        }
    }
}

@Suppress("unused")
class HzwRefundProcurator(sid: String) : HzwRefundPorter(sid) {

    override val cron = "0/10 * * * * ?"

    override fun getParameters(store: Store): Pair<List<Any>, Boolean> {
        return listOf(1) to false
    }
}